home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 002 / texttool.arc / INDEX.C next >
C/C++ Source or Header  |  1987-02-11  |  8KB  |  256 lines

  1. /* index.c
  2.    a program to prepare an ordered list of "words" and their frequencies. 
  3.    a "word" is defined as a string of alphabetic characters (A-Z, a-z) 
  4.    or digits (0-9), freely intermixed. */
  5.  
  6. #include        <stdio.h>
  7. #include        <ctype.h>
  8.  
  9. #define         YES      1
  10. #define         NO       0
  11. #define         WORDLEN 20
  12. #define         LETTER   0
  13. #define         NUMBER   1
  14. #define         OTHER    2
  15. #define         KILOBYTE  1024
  16.  
  17.    char buffer[BUFSIZ];
  18.  
  19.    typedef struct list  
  20.                 {
  21.                 char *wd;            /*text for a unique word */
  22.                 int count;           /* count the occurences of the word*/
  23.                 struct list *left;   /* left pointer*/
  24.                 struct list *right;  /* right pointer*/
  25.                 } LIST, *LISTPTR ;
  26.    int nwords;
  27.    int n_unique_words;
  28.  
  29. main (argc,  argv)    /*  index.c   */
  30.  
  31. int argc;
  32. char *argv[];
  33.  
  34. {
  35.    LISTPTR root;
  36.    LISTPTR countword();
  37.    char word[WORDLEN];
  38.    int c,                    /* individual character */
  39.        j,                    /* counter for word - output */
  40.        i,                    /* counter for buffer - input */
  41.        nchar,                /* number of characters read from text file */
  42.        inword,               /* flag - indicates whether we are in a word */
  43.        accpt;                /* return value of accept(): indicates whether
  44.                                 a character is "in" a word.  These include
  45.                                 characters, (single) hyphens, (single)
  46.                                 apostrophies, but not numbers and other ascii 
  47.                                 values   */
  48.     int bufno = 0;
  49.  
  50.    FILE *fopen(),
  51.         *fp;
  52.    FILE *fpout;
  53.    int fread();
  54.    char out_file[13];
  55.  
  56.  
  57. /*search the command line for a file to read: exit if none */
  58.  
  59.    if (argc == 1) 
  60.    {  printf ("no file to index");
  61.       exit (1);
  62.    }
  63.  
  64.    else
  65.    {
  66.         while (--argc > 0)
  67.                 if ((fp = fopen(*++argv, "r")) == NULL)
  68.                 {       printf("index: can't open %s\n",*argv);
  69.                         break;
  70.                 }
  71.         strcpy(out_file,*argv);
  72.         for (i=0; i<9 && out_file[i] != '.'; ++i)
  73.               ;
  74.         out_file[++i] = NULL;
  75.         strcat (out_file, "txt");                  /* works */
  76.         printf("OUTPUT file: %s\n",out_file);
  77.         fpout = fopen(out_file, "wb");             /*open output file*/
  78.         if (fpout == NULL)
  79.         {
  80.               printf ("index: cannot open output file");
  81.               exit(1);
  82.         }
  83.          printf("fpout = %d\n",fpout);
  84.    }
  85.  
  86.    inword = NO;
  87.    root = NULL;   
  88.    n_unique_words = c = j =  0;
  89.  
  90.    while ( nchar = fread (buffer, 1, BUFSIZ , fp) )
  91.                        /* process until no characters returned (EOF)*/
  92.  
  93.    {
  94. /*   printf("nchar = %d, bufno = %d\n",nchar,++bufno);*/
  95. /*   printf("buffer contents %s\n",buffer);*/
  96.  
  97.          for (i=0; i < nchar ; ++i)  /*nchar is a count.  nchar-1 is last valid
  98.                                        index */
  99.          {
  100.               if ((accpt = accept( c = buffer[i])) != LETTER)
  101.               {
  102.                    if (inword == YES)
  103.                    {
  104.                         word[j] = '\0';
  105. /*                        printf("%s  \n",word);*/
  106.                         if (validword(word) )
  107.                                      root = countword (root,word,j+1);
  108.                         inword = NO;
  109.                         j = 0;
  110.                    }
  111. /*                   if(c == '\n')
  112.                         inword = NO;*/
  113.               }
  114.               else if (accpt == LETTER )
  115.               {
  116.                    if (j < WORDLEN) word[j++] = tolower (c);
  117.                    inword = YES;
  118.               }
  119.          }
  120. /*         printf("finished running the buffer \n");*/
  121. /*         printf("feof(fp) %d, inword %d\n",feof(fp),inword);*/
  122.  
  123.          if (feof(fp) && inword == YES)
  124.          {
  125.               word[j] = '\0';
  126.               if (validword(word) )
  127.                            root = countword (root, word,j+1);
  128.          }
  129.    }
  130. printf("completed reading file -- output ?follows?\n");
  131.  
  132. sprintf (buffer,"total words %4d",n_unique_words);  /*write total*/
  133. strcat (buffer, "\r\n");                          /*mandatory control chars*/
  134. fwrite (buffer, 1, strlen(buffer), fpout);
  135. treeprint(root,fpout);                                /*call recursive print*/
  136.  
  137. }  /*end of program */
  138.  
  139. /* RECURSIVE routine to build a tree of words and their frequences*/
  140. /* the final return address is the address of the ROOT node */
  141.  
  142. struct list *countword (p, word, wd_len) /*install word at or below p  */
  143.    struct list *p;                       /*count word if already in tree*/
  144.    char word[];
  145.    int wd_len;                         /* including the terminating NULL */
  146. {
  147.         static char *wd_buffer = NULL,
  148.                     *wd_buffer_top = NULL;
  149.         char *malloc();
  150.         int cond;
  151.  
  152. /*         printf(".");*/
  153.  
  154. /*         printf("countword: %s len= %d\n",word,wd_len);*/
  155.  
  156.         if (p == NULL)    /*new word - make a new node */
  157.          {
  158.               p = (LISTPTR ) malloc (sizeof(LIST));  /*allocade a node*/
  159.               if (p == NULL) 
  160.               {
  161.                     /*error handling */
  162.                    ;
  163.               }
  164.               n_unique_words += 1;  /* count the new word */
  165.  
  166.    /*====make sure there is enough room to store a new word.  If not allocate space*/
  167.  
  168.               if ((wd_buffer_top - wd_buffer) < wd_len)  /*how much space remains?*/
  169.               {
  170.                    wd_buffer = (char *) malloc(KILOBYTE); /*allocate a chunk*/
  171.                    if (wd_buffer == NULL)    /*if no space available, take action*/
  172.                         {
  173.                            /* error handling */
  174.                              ;
  175.                         }
  176.                    wd_buffer_top = wd_buffer + KILOBYTE ; /* top of chunk (+1) */
  177.               }
  178.               p -> wd = wd_buffer;  /* pointer to the new word*/
  179.               while (*wd_buffer++ = *word++)   /*copy the word /*
  180.                          ;                     /*to a home */
  181.               p -> count = 1;               /* count it */
  182.               p -> left = p->right = NULL;  /*null the child pointers*/
  183.          }
  184.          else if ((cond = strcmp(word, p->wd)) == 0)
  185.               p->count++;                                 /*repeated word*/
  186.  
  187.          else if (cond < 0)                            /*lower, go left*/
  188.               p->left = countword (p->left,word,wd_len);
  189.  
  190.          else                                          /*greater, go right*/
  191.               p->right = countword (p->right,word,wd_len);
  192.  
  193.          return(p);
  194. }
  195.  
  196.  
  197. strcmp (s, t)
  198.    char s[];
  199.    char t[];
  200. {
  201.    int diff;
  202.  
  203.    while ((diff = *s-*t) == 0 && *t != '\0' && *s != '\0')
  204.    {
  205.          ++s;
  206.          ++t;
  207.    }
  208.  
  209.    return (diff);
  210. }
  211.  
  212. treeprint(p,fpout)
  213. struct list *p;
  214. FILE *fpout;
  215. {
  216.  
  217.    if (p!=NULL)
  218.    {
  219.         treeprint(p->left,fpout);
  220.         sprintf(buffer,"%4d %s",p->count,p->wd);
  221.         strcat( buffer, "\r\n");
  222.         fwrite (buffer, 1, strlen(buffer), fpout);
  223.         treeprint(p->right,fpout);
  224.    }
  225.  
  226. }
  227.  
  228.  
  229. accept (c)
  230. char c;
  231. {
  232.  
  233. if (isalpha(c) || c == '\'') return (LETTER);
  234. if (isdigit(c)) return (NUMBER);
  235.  
  236. return (OTHER);
  237. }
  238.  
  239. validword (w)
  240. char w[];
  241. {
  242.     int i;
  243.  
  244.     if (w[0] == '-' ) return(0); /*initial hyphens are invalid */
  245.  
  246.     for (i=0; i<WORDLEN-1 && w[i] !=NULL; ++i)
  247.     {
  248. /*         if (w[i] == '-' && w[i+1] == '-') return(0); */
  249.                      /* double embedded '-'is invalid */
  250.          if(w[i] == '\'' && w[i+1] == '\'') return(0); 
  251.                      /*double apostrophie is invalid */
  252.     }
  253.     return (1);
  254. }
  255.  
  256.